package cn.xo68.boot.webgather.resolve.htmlunit;

import cn.xo68.boot.webgather.properties.WebGatherProperties;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.WebClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.concurrent.LinkedBlockingQueue;

/**
 * 收集执行器
 * @author  wuxie
 * @date 2018-7-16
 */
public class WebClientFactory implements FactoryBean<WebClient>,ApplicationContextAware,InitializingBean,DisposableBean {

    private static final Logger logger=LoggerFactory.getLogger(WebClientFactory.class);

    private ApplicationContext applicationContext;

    private WebGatherProperties webGatherProperties;

    private LinkedBlockingQueue<WebClient> linkedBlockingQueue=null;


    public WebGatherProperties getWebGatherProperties() {
        return webGatherProperties;
    }

    public void setWebGatherProperties(WebGatherProperties webGatherProperties) {
        this.webGatherProperties = webGatherProperties;
    }

    public boolean releaseExecutor(WebClient webClient){
        return linkedBlockingQueue.offer(webClient);
    }

    @Override
    public WebClient getObject() throws Exception {
        WebClient webClient= linkedBlockingQueue.poll();
        if(webClient==null){
            // 1创建WebClient

            webClient=new WebClient(BrowserVersion.CHROME);
            // 2 启动JS
            webClient.getOptions().setJavaScriptEnabled(true);
            // 3 禁用Css，可避免自动二次請求CSS进行渲染
            webClient.getOptions().setCssEnabled(true);
            // 4 启动客戶端重定向
            webClient.getOptions().setRedirectEnabled(true);
            // 5 js运行错誤時，是否拋出异常
            webClient.getOptions().setThrowExceptionOnScriptError(false);
            webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
            // 6 设置超时
            webClient.getOptions().setTimeout(webGatherProperties.getWebTimeout());
            webClient.setAjaxController(new NicelyResynchronizingAjaxController());//很重要，设置支持AJAX
            //gatherExecutor=new GatherExecutor(webClient, this.executorService);
        }
        return webClient;
    }

    @Override
    public Class<?> getObjectType() {
        return GatherExecutor.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        linkedBlockingQueue=new LinkedBlockingQueue<>(200);
    }

    @Override
    public void destroy() throws Exception {
        if(linkedBlockingQueue!=null){
            WebClient webClient= linkedBlockingQueue.poll();
            while (webClient != null){
                try {
                    webClient.close();
                }catch (Exception e){

                }
                webClient= linkedBlockingQueue.poll();
            }
        }

   }


}
